import { checkIsNodeStyleDataKey } from '../../../utils/index';

const backgroundStyleProps = [
    'backgroundColor',
    'backgroundImage',
    'backgroundRepeat',
    'backgroundPosition',
    'backgroundSize',
];

//  样式类
class Style {
    //   设置背景样式
    static setBackgroundStyle(el, themeConfig) {
        if (!el) return;
        // 缓存容器元素原本的样式
        if (!Style.cacheStyle) {
            Style.cacheStyle = {};
            let style = window.getComputedStyle(el);
            backgroundStyleProps.forEach((prop) => {
                Style.cacheStyle[prop] = style[prop];
            });
        }
        // 设置新样式
        let {
            backgroundColor,
            backgroundImage,
            backgroundRepeat,
            backgroundPosition,
            backgroundSize,
        } = themeConfig;
        el.style.backgroundColor = backgroundColor;
        if (backgroundImage && backgroundImage !== 'none') {
            el.style.backgroundImage = `url(${backgroundImage})`;
            el.style.backgroundRepeat = backgroundRepeat;
            el.style.backgroundPosition = backgroundPosition;
            el.style.backgroundSize = backgroundSize;
        } else {
            el.style.backgroundImage = 'none';
        }
    }

    // 移除背景样式
    static removeBackgroundStyle(el) {
        if (!Style.cacheStyle) return;
        backgroundStyleProps.forEach((prop) => {
            el.style[prop] = Style.cacheStyle[prop];
        });
        Style.cacheStyle = null;
    }

    //  构造函数
    constructor(ctx) {
        this.ctx = ctx;
        // 箭头图标
        this._markerPath = null;
        this._marker = null;
        // 渐变背景
        this._gradient = null;
    }

    //  合并样式
    merge(prop, root) {
        let themeConfig = this.ctx.mindMap.themeConfig;
        let defaultConfig = null;
        let useRoot = false;
        if (root) {
            // 使用最外层样式
            useRoot = true;
            defaultConfig = themeConfig;
        } else if (this.ctx.isGeneralization) {
            // 概要节点
            defaultConfig = themeConfig.generalization;
        } else if (this.ctx.layerIndex === 0) {
            // 根节点
            defaultConfig = themeConfig.root;
        } else if (this.ctx.layerIndex === 1) {
            // 二级节点
            defaultConfig = themeConfig.second;
        } else {
            // 三级及以下节点
            defaultConfig = themeConfig.node;
        }
        let value = '';
        // 优先使用节点本身的样式
        if (this.getSelfStyle(prop) !== undefined) {
            value = this.getSelfStyle(prop);
        } else if (defaultConfig[prop] !== undefined) {
            // 否则使用对应层级的样式
            value = defaultConfig[prop];
        } else {
            // 否则使用最外层样式
            value = themeConfig[prop];
        }
        if (!useRoot) {
            this.addToEffectiveStyles({
                [prop]: value,
            });
        }
        return value;
    }

    //  获取某个样式值
    getStyle(prop, root) {
        return this.merge(prop, root);
    }

    //  获取自身自定义样式
    getSelfStyle(prop) {
        return this.ctx.getData(prop);
    }

    // 更新当前节点生效的样式数据
    addToEffectiveStyles(styles) {
        this.ctx.effectiveStyles = {
            ...this.ctx.effectiveStyles,
            ...styles,
        };
    }

    //  矩形
    rect(node) {
        this.shape(node);
        node.radius(this.merge('borderRadius'));
    }

    // 形状
    shape(node) {
        const styles = {
            gradientStyle: this.merge('gradientStyle'),
            startColor: this.merge('startColor'),
            endColor: this.merge('endColor'),
            startDir: this.merge('startDir'),
            endDir: this.merge('endDir'),
            fillColor: this.merge('fillColor'),
            borderColor: this.merge('borderColor'),
            borderWidth: this.merge('borderWidth'),
            borderDasharray: this.merge('borderDasharray'),
        };
        if (styles.gradientStyle) {
            if (!this._gradient) {
                this._gradient = this.ctx.nodeDraw.gradient('linear');
            }
            this._gradient.update((add) => {
                add.stop(0, styles.startColor);
                add.stop(1, styles.endColor);
            });
            this._gradient.from(...styles.startDir).to(...styles.endDir);
            node.fill(this._gradient);
        } else {
            node.fill({
                color: styles.fillColor,
            });
        }
        // 节点使用横线样式，不需要渲染非激活状态的边框样式
        // if (
        //   !this.ctx.isRoot &&
        //   !this.ctx.isGeneralization &&
        //   this.ctx.mindMap.themeConfig.nodeUseLineStyle &&
        //   !this.ctx.getData('isActive')
        // ) {
        //   return
        // }
        node.stroke({
            color: styles.borderColor,
            width: styles.borderWidth,
            dasharray: styles.borderDasharray,
        });
    }

    //  文字
    text(node) {
        const styles = {
            color: this.merge('color'),
            fontFamily: this.merge('fontFamily'),
            fontSize: this.merge('fontSize'),
            fontWeight: this.merge('fontWeight'),
            fontStyle: this.merge('fontStyle'),
            textDecoration: this.merge('textDecoration'),
        };
        node.fill({
            color: styles.color,
        }).css({
            'font-family': styles.fontFamily,
            'font-size': styles.fontSize + 'px',
            'font-weight': styles.fontWeight,
            'font-style': styles.fontStyle,
            'text-decoration': styles.textDecoration,
        });
    }

    // 生成内联样式
    createStyleText() {
        const styles = {
            color: this.merge('color'),
            fontFamily: this.merge('fontFamily'),
            fontSize: this.merge('fontSize'),
            fontWeight: this.merge('fontWeight'),
            fontStyle: this.merge('fontStyle'),
            textDecoration: this.merge('textDecoration'),
        };
        return `
      color: ${styles.color};
      font-family: ${styles.fontFamily};
      font-size: ${styles.fontSize + 'px'};
      font-weight: ${styles.fontWeight};
      font-style: ${styles.fontStyle};
      text-decoration: ${styles.textDecoration}
    `;
    }

    // 获取文本样式
    getTextFontStyle() {
        const styles = {
            color: this.merge('color'),
            fontFamily: this.merge('fontFamily'),
            fontSize: this.merge('fontSize'),
            fontWeight: this.merge('fontWeight'),
            fontStyle: this.merge('fontStyle'),
            textDecoration: this.merge('textDecoration'),
        };
        return {
            italic: styles.fontStyle === 'italic',
            bold: styles.fontWeight,
            fontSize: styles.fontSize,
            fontFamily: styles.fontFamily,
        };
    }

    //  html文字节点
    domText(node, fontSizeScale = 1) {
        const styles = {
            color: this.merge('color'),
            fontFamily: this.merge('fontFamily'),
            fontSize: this.merge('fontSize'),
            fontWeight: this.merge('fontWeight'),
            fontStyle: this.merge('fontStyle'),
            textDecoration: this.merge('textDecoration'),
        };
        node.style.color = styles.color;
        node.style.textDecoration = styles.textDecoration;
        node.style.fontFamily = styles.fontFamily;
        node.style.fontSize = styles.fontSize * fontSizeScale + 'px';
        node.style.fontWeight = styles.fontWeight || 'normal';
        node.style.fontStyle = styles.fontStyle;
    }

    //  标签文字
    tagText(node, style) {
        node.fill({
            color: '#fff',
        }).css({
            'font-size': style.fontSize + 'px',
        });
    }

    //  标签矩形
    tagRect(node, style) {
        node.fill({
            color: style.fill,
        });
        if (style.radius) {
            node.radius(style.radius);
        }
    }

    //  内置图标
    iconNode(node) {
        node.attr({
            fill: this.merge('color'),
        });
    }

    //  连线
    line(line, { width, color, dasharray } = {}, enableMarker, childNode) {
        line.stroke({ color, dasharray, width }).fill({ color: 'none' });
        // 可以显示箭头
        if (enableMarker) {
            const showMarker = this.merge('showLineMarker', true);
            const childNodeStyle = childNode.style;
            // 显示箭头
            if (showMarker) {
                // 创建子节点箭头标记
                childNodeStyle._marker =
                    childNodeStyle._marker || childNodeStyle.createMarker();
                // 设置样式
                childNodeStyle._markerPath.stroke({ color }).fill({ color });
                // 箭头位置可能会发生改变，所以需要先删除
                line.attr('marker-start', '');
                line.attr('marker-end', '');
                const dir = childNodeStyle.merge('lineMarkerDir');
                line.marker(dir, childNodeStyle._marker);
            } else if (childNodeStyle._marker) {
                // 不显示箭头，则删除该子节点的箭头标记
                line.attr('marker-start', '');
                line.attr('marker-end', '');
                childNodeStyle._marker.remove();
                childNodeStyle._marker = null;
            }
        }
    }

    // 创建箭头
    createMarker() {
        return this.ctx.lineDraw.marker(20, 20, (add) => {
            add.ref(8, 5);
            add.size(20, 20);
            add.attr('markerUnits', 'userSpaceOnUse');
            add.attr('orient', 'auto-start-reverse');
            this._markerPath = add.path('M0,0 L2,5 L0,10 L10,5 Z');
        });
    }

    //  概要连线
    generalizationLine(node) {
        node.stroke({
            width: this.merge('generalizationLineWidth', true),
            color: this.merge('generalizationLineColor', true),
        }).fill({ color: 'none' });
    }

    //  展开收起按钮
    iconBtn(node, node2, fillNode) {
        let { color, fill, fontSize, fontColor } = this.ctx.mindMap.opt
            .expandBtnStyle || {
            color: '#808080',
            fill: '#fff',
            fontSize: 12,
            strokeColor: '#333333',
            fontColor: '#333333',
        };
        node.fill({ color: color });
        node2.fill({ color: color });
        fillNode.fill({ color: fill });
        if (this.ctx.mindMap.opt.isShowExpandNum) {
            node.attr({
                'font-size': fontSize + 'px',
                'font-color': fontColor,
            });
        }
    }

    // 是否设置了自定义的样式
    hasCustomStyle() {
        let res = false;
        Object.keys(this.ctx.getData()).forEach((item) => {
            if (checkIsNodeStyleDataKey(item)) {
                res = true;
            }
        });
        return res;
    }

    // hover和激活节点
    hoverNode(node) {
        const hoverRectColor =
            this.merge('hoverRectColor') || this.ctx.mindMap.opt.hoverRectColor;
        const hoverRectRadius = this.merge('hoverRectRadius');
        node.radius(hoverRectRadius).fill('none').stroke({
            color: hoverRectColor,
        });
    }

    // 所属节点被删除时的操作
    onRemove() {
        if (this._marker) {
            this._marker.remove();
            this._marker = null;
        }
        if (this._markerPath) {
            this._markerPath.remove();
            this._markerPath = null;
        }
        if (this._gradient) {
            this._gradient.remove();
            this._gradient = null;
        }
    }
}

Style.cacheStyle = null;

export default Style;
